package com.zhongkai.service;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import com.zhongkai.dao.BaseDao;
import com.zhongkai.tools.DateManageTool;

@Component
public class CommonService{
	@Resource
	private BaseDao baseDao;
	
	/**
	 * 保存记录
	 * @param object
	 * @throws Exception 
	 */
	public void save(Object object) throws Exception {
		baseDao.insert(object);
	}

	/**
	 * 更新记录
	 * @param object
	 */
	public void update(Object object) throws Exception {
		baseDao.update(object);
	}

	/**
	 * 删除记录
	 * @param object
	 */	
	public void delete(Object object) throws Exception {		
		baseDao.delete(object);
	}

	/**
	 * 指定相应的实体类，并根据id查找记录
	 * @param entityId
	 * @return
	 */
	public Object findById(Object object,Serializable entityId) throws Exception {
		return baseDao.selectById(object.getClass(), entityId);
		
	}

	/**
	 * 指定相应的实体类，并根据id删除记录
	 * @param entityId
	 */
	public void delById(Object object,Serializable entityId) throws Exception{
		Object getObject=this.findById(object, entityId);
		if(getObject!=null){
			baseDao.delete(getObject);
		}
	}
	
	/**
	 * 根据实体类名，搜索所有的记录
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	public List findAll(String entityName) throws Exception{
		return baseDao.select("from "+entityName);
	}
	
	/**
	 * 根据实体类名，那条件搜索对应的记录总数
	 */
	@SuppressWarnings("unchecked")
	public Integer count(String entityName,String[] columnName,String[] columnValue) throws Exception{
		List records= findByColumns(entityName, columnName, columnValue);
		if(records!=null&&records.size()>0){
			return records.size();
		}else return 0;
	}
	
	/*
	 * 批量更新
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void updateList(List objects) throws Exception{
		for(int i=0;i<objects.size();i++){
			baseDao.update(objects.get(i));
		}
	}
	
	/*
	 * 批量保存
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void saveList(List objects) throws Exception{
		for(int i=0;i<objects.size();i++){
			baseDao.insert(objects.get(i));
		}
	}

	
	/**
	 * 指定实体字段和该字段的值，进行记录搜索，返回单条记录
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")	
	public Object findByName(String entityName,String[] columnName,Object[] columnValue) throws Exception{		
		List objects=this.findByColumns(entityName, columnName, columnValue);
		if(objects!=null&&objects.size()>0){
			return objects.get(0);
		}else {
			return null;
		}		
	}

	/**
	 * 指定实体字段和该字段的值，进行记录搜索,返回结果集
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	public List findByColumns(String entityName,String[] columnName,Object[] columnValue) throws Exception{
		String whereSql=createContionsSql(entityName,columnName,columnValue);//userid=1 and userName='hwb'或者//userid=1 and userName in('hwb','fzx')
		List objects=baseDao.select(whereSql);
		if(objects!=null&&objects.size()>0){
			return objects;
		}else {
			return null;
		}		
	}
	
	
	/**
	 *根据条件， 拼接查找最大的字段记录语句
	 * @param maxCol
	 * @param entityName
	 * @param columnName
	 * @param columnValue
	 * @return
	 */
	public String createFindMaxSql(String maxCol,String entityName,String[] columnName,Object[] columnValue){
		StringBuilder hql=new StringBuilder();
		hql.append("select max(");
		hql.append(maxCol);
		hql.append(")");
		hql.append(createContionsSql(entityName,columnName,columnValue));//userid=1 and userName='hwb'或者//userid=1 and userName in('hwb','fzx')
		return hql.toString();
	}
	
	/*
	 * 根据条件，获取某个字段的最大值:
	 * 注意：Object是单个字段的值：如收date的最大值，返回的类型就是Date
	 */
	@SuppressWarnings("unchecked")
	public Object  getMax(String maxCol,String entityName,String[] columnName,Object[] columnValue) throws Exception{
		 String maxSql=createFindMaxSql(maxCol,entityName,columnName,columnValue);
	 	List records=baseDao.select(maxSql);
		 if(records!=null&&records.size()>0){
			 return records.get(0);
		 }else return null;
	}
	

	
	
	/**
	 * 多条件查询：
	 * 如：select * from User where userId=1 and userName in('hwb','fzx');
	 * @param entityName
	 * @param columnName
	 * @param columnValue
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public List findObjects(String entityName,String[] columnName,Object[] columnValue) throws Exception{
		String queryString=this.createContionsSql(entityName,columnName,columnValue);// userid=1 and userName in() 
		return baseDao.select(queryString);
	}
	
	/**
	 * 查找分组
	 * @param entityName
	 * @param columnName
	 * @param columnValue
	 * @param groupColumnName
	 * @return
	 * @throws Exception
	 */
	public List findGroups(String entityName,String[] columnName,Object[] columnValue,Object[] groupColumnName) throws Exception{
		String groupSql=groupBySql( entityName, columnName, columnValue, groupColumnName);
		return baseDao.select(groupSql);
	}
	

	
	
	/*多条件查询:多少个and拼接就添加相应的value值，而对于in的存放到数组中。。。。。。。。
	 * 如：select * from User where userId=1 and userName in('hwb','fzx') and age between 1 and 6;
	 * ----->sql("User",String[]{"userId","userName"},Object[]{'1',Object[]{'hwb','fzx'}})
	 * 注意：有多少个字段，就对应多少个值
	 * 
	 * 测试例子：
	 * String test=businessQueryService.createContionsSql("TDjCcywcl", new String[]{"czrDm","ywlxDm","user","age"}, new Object[]{null,null,null,null});
		System.out.println("测试sql：====="+test);
	 * */
	public String createContionsSql(String entityName,String[] columnName,Object[] columnValue){
		StringBuilder whereSql=new StringBuilder();
		whereSql.append(" from ").append(entityName);
		int length=columnValue.length;
		int num=0;
		for(;num<length;num++){//判断val值全部不能同时为空
			if(columnValue[num]!=null) break; 
		}
		if(length>0&&num<length){
			whereSql.append(" where ");
		}else return whereSql.toString();		
		for(int i=0;i<length;i++){
			if(columnValue[i]!=null){
				boolean isAray=columnValue[i].getClass().isArray();//判断该value值是否为数组，从而拼接in('sky','test')函数
				if(isAray){
					Object[] orVals=(Object[])columnValue[i];
					if(orVals.length==3&&orVals[2]==null){//拼接between语句，【针对val数组长度为3，并且第三个value值为空】
						whereSql.append(createbetweenSql(columnName[i],orVals));
					}else{
						whereSql.append(createOrSql(columnName[i],orVals));
					}
				}else{
					whereSql.append(columnName[i]).append("='").append(columnValue[i]).append("'");					
				}
				whereSql.append(" and ");
			}
		}
		return whereSql.substring(0,whereSql.length()-5);//截取sql语句的最后" and "
	}
	
	
	/**
	 * sql的分组查询
	 * @param entityName
	 * @param columnName
	 * @param columnValue
	 * @param groupColumnName
	 * @return
	 */
	public String groupBySql(String entityName,String[] columnName,Object[] columnValue,Object[] groupColumnName){
		String secondsql=createContionsSql(entityName, columnName, columnValue);
		StringBuilder groupSql=new StringBuilder();
		int length=groupColumnName.length;
		if(groupColumnName!=null&&length>0){
			groupSql.append("select ");
			for(int i=0;i<length-1;i++){
				groupSql.append(groupColumnName[i]).append(",");				
			}
			groupSql.append(groupColumnName[length-1]);
			groupSql.append(secondsql).append(" group by ");			
			
			for(int i=0;i<length-1;i++){
				groupSql.append(groupColumnName[i]).append(", ");			
			}
			groupSql.append(groupColumnName[length-1]);
		}
			return groupSql.toString();
	}


	/**
	 * 为某个字段拼接in函数sql语句：userName in('hwb','fzx')
	 * @param columnName
	 * @param columnVal
	 * @return
	 */
	public String createOrSql(String columnName,Object[] columnVal){
		StringBuilder orSql=new StringBuilder();
		orSql.append(columnName).append(" in('");
		int length=columnVal.length;
		for(int i=0;i<length-1;i++){
			orSql.append(columnVal[i]).append("','");
		}
		orSql.append(columnVal[length-1]).append("')");
		return orSql.toString();		
	}
	
	/**
	 * 为字段拼接范围比较：age between 10 and 50，即age>=10&&age<=50
	 * 如：createbetweenSql("age",new Object[]{10,50,null})
	 * @param columnName
	 * @param columnVal
	 * @return
	 */
	public String createbetweenSql(String columnName,Object[] columnVal){
		StringBuilder betweenSql=new StringBuilder();
		if(columnVal[0] instanceof Date &&columnVal[1] instanceof Date){
			SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");//对于日期类型的处理
			String small=df.format(columnVal[0]);
			String big=df.format(DateManageTool.calculateDay((Date)columnVal[1], "plus",1));//结束日期2011-08-15加1，保证包含时分秒的操作日期为2011-08-15 15:30:26在结束日期2011-08-15这天范围内
			betweenSql.append(columnName).append(" between ").append("'").append(small).append("' and '").append(big).append("'");			
		}else{
			betweenSql.append(columnName).append(" between ").append("'").append(columnVal[0]).append("' and '").append(columnVal[1]).append("'");			
		}
		return betweenSql.toString();
	}


	


}
